from django.core.exceptions import ValidationError
from django.shortcuts import render, redirect
from django import forms
from django.http import JsonResponse
from utils.bootstrap import BootStrapForm
from utils.encrypt import md5
from utils.response import BaseResponse
from django.utils.safestring import mark_safe
from web import models
from utils.pager import Pagination
from django.db.models import Q
from django.db import transaction
from utils.group import Option,NbSearchGroup

def customer_list(request):
    # 1. 获取客户列表
    # 1.1 客户是可以被逻辑删除
    # 1.2 级别被删了, 下属有客户咋办？[逻辑删除]
    #        -- 修改级别删除的逻辑   查询是否有关联数据，有关联数据，不允许删除。
    #        -- 将下属客户设置成一个默认值， 例如 :Null
    #        -- 不做任何行为  queryset = models.Customer.objects.filter(active=1, level__active=1)

    # 主动跨表 可以提高查询速度
    search_group = NbSearchGroup(
        request,
        models.Customer,
        Option('level',db_condition={'active':1}), # forignkey
    )

    keyword = request.GET.get("keyword", "").strip()
    con = Q()
    if keyword:
        con.connector = 'OR'
        con.children.append(('username__contains', keyword))
        con.children.append(('mobile__contains', keyword))
        con.children.append(('level__title__contains', keyword))

    queryset = models.Customer.objects.filter(con).filter(**search_group.get_condition).filter(active=1).select_related('level')
    obj = Pagination(request, queryset)

    # start_page = 1
    # end_page = total_page

    context = {
        'queryset': queryset[obj.start:obj.end],
        "pager_string": obj.html(),
        'keyword': keyword,
        'search_group': search_group,
    }
    return render(request, 'customer_list.html', context)


class CustomerModelForm(BootStrapForm, forms.ModelForm):
    exclude_field_list = ['level']

    confirm_password = forms.CharField(
        label='重复密码',
        widget=forms.PasswordInput(render_value=True)
    )

    # mobile =forms.CharField(
    #     label="手机号",
    #     validators=[RegexValidator(r'^\d{11}$','手机号格式错误'),],
    # )

    class Meta:
        model = models.Customer
        fields = ['username', 'mobile', 'password', 'confirm_password', 'level']
        widgets = {
            'password': forms.PasswordInput(render_value=True),
            'level': forms.RadioSelect(attrs={'class': 'form-radio'})
        }

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # some_data = request.GET.get('')
        # self.fields['level'].queryset = models.Level.objects.filter(active=1, some_data)
        self.fields['level'].queryset = models.Level.objects.filter(active=1)

    def clean_password(self):
        password = self.cleaned_data['password']
        return md5(password)

    def clean_confirm_password(self):
        password = self.cleaned_data.get('password')
        confirm_password = md5(self.cleaned_data.get('confirm_password', ''))
        if password != confirm_password:
            raise ValidationError("密码不一致")
        return confirm_password

    # def clean_mobile(self):
    #     mobile = self.cleaned_data['mobile']
    #     import re
    #     from django.core.exceptions import ValidationError
    #     if not re.match(r'^\d{11}$', mobile):
    #         raise ValueError("格式错误")
    #     return mobile


def customer_add(request):
    if request.method == 'GET':
        form = CustomerModelForm(request)  # 可以传参数
        return render(request, "form2.html", {"form": form})

    form = CustomerModelForm(request, data=request.POST)
    if not form.is_valid():
        return render(request, "form2.html", {"form": form})

    form.instance.creator_id = request.nb_user.id
    form.save()
    return redirect("/customer/list/")


class CustomerEditModelForm(BootStrapForm, forms.ModelForm):
    exclude_field_list = ['level']

    class Meta:
        model = models.Customer
        fields = ['username', 'mobile', 'level']
        widgets = {
            'password': forms.PasswordInput(render_value=True),
            'level': forms.RadioSelect(attrs={'class': 'form-radio'})
        }

    def __init__(self, request, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['level'].queryset = models.Level.objects.filter(active=1)


def customer_edit(request, pk):
    instance = models.Customer.objects.filter(id=pk, active=1).first()
    if request.method == 'GET':
        form = CustomerEditModelForm(request, instance=instance)
        return render(request, 'form2.html', {"form": form})

    form = CustomerEditModelForm(request, instance=instance, data=request.POST)
    if not form.is_valid():
        return render(request, "form2.html", {"form": form})
    form.save()

    # 保持编辑保存后 仍然会显示刚保存的页面 不会弹回第一页首页
    # 1.获取filter
    # filter_string = request.GET.get('_filter')
    # if not filter_string:
    #     return redirect("/customer/list/")
    # # url 拼接
    # return redirect("/customer/list/?{}".format(filter_string))
    # 保持编辑保存后 仍然会显示刚保存的页面 不会弹回第一页首页
    from utils.link import filter_reverse
    # 转向保存的那一页的url
    return redirect(filter_reverse(request, "/customer/list/"))


class CustomerResetModelForm(BootStrapForm, forms.ModelForm):
    confirm_password = forms.CharField(
        label='重复密码',
        widget=forms.PasswordInput(render_value=True))

    class Meta:
        model = models.Customer
        fields = ['password', 'confirm_password']
        widgets = {
            'password': forms.PasswordInput(render_value=True),
        }

    def clean_password(self):
        password = self.cleaned_data['password']
        return md5(password)

    def clean_confirm_password(self):
        password = self.cleaned_data.get('password')
        confirm_password = md5(self.cleaned_data.get('confirm_password', ''))
        if password != confirm_password:
            raise ValidationError("密码不一致")
        return confirm_password


def customer_reset(request, pk):
    if request.method == 'GET':
        form = CustomerResetModelForm()
        return render(request, "form2.html", {"form": form})
    instance = models.Customer.objects.filter(id=pk, active=1).first()
    form = CustomerResetModelForm(data=request.POST, instance=instance)
    if not form.is_valid():
        return render(request, "form2.html", {"form": form})
    form.save()
    return redirect("/customer/list/")


def customer_delete(request):
    cid = request.GET.get('cid', 0)
    if not cid:
        res = BaseResponse(status=False, detail="请选择要删除的数据")
        return JsonResponse(res.dict)

    exists = models.Customer.objects.filter(id=cid, active=1).exists()
    if not exists:
        res = BaseResponse(status=False, detail="要删除的数据不存在")
        return JsonResponse(res.dict)

    models.Customer.objects.filter(id=cid, active=1).update(active=0)
    res = BaseResponse(status=True)
    return JsonResponse(res.dict)


class ChargeModelForm(BootStrapForm, forms.ModelForm):
    # 静态变量
    # charge_type = forms.TypeChoiceField(
    #     label="类型",
    #     choices=[(1, 1,"充值"), (2, "扣款")]  # 只适合固定数据，不适合去数据库表中数据 此时字符串
    #     coerce = int  此时变为整型 才可以
    # )
    class Meta:
        model = models.TransactionRecord
        fields = ['charge_type', 'amount']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['charge_type'].choices = [(1, "充值"), (2, "扣款")]
        # self.fields['creator'].choices = models.Administrator.objects.filter().values_list('id', 'username')


def customer_charge(request, pk):
    """交易记录"""
    queryset = models.TransactionRecord.objects.filter(customer_id=pk, customer__active=1, active=1).select_related(
        'customer').order_by('-id')
    # 分页调用
    pager = Pagination(request, queryset)

    form = ChargeModelForm()
    # return render(request, "customer_charge.html", {"pager": pager, "form": form,'pk':pk})
    return render(request, 'customer_charge.html', locals())


def customer_charge_add(request, pk):
    print(pk)
    print(request.POST)  # charge_type=类型 amount = 金额
    form = ChargeModelForm(data=request.POST)
    if not form.is_valid():
        return JsonResponse({'status': False, 'detail': form.errors})

    # 如果校验成功
    amount = form.cleaned_data['amount']
    charge_type = form.cleaned_data['charge_type']
    # 对当前操作的客户 进行更新操作，账户余额:增加、减少

    from django.db import transaction  # 事务保证要成功都成功 要失败都失败
    try:
        with transaction.atomic():
            # 对当前操作的客户进行更新操作，账户余额：增加、减少 + 锁 保证加减金额有先后顺序不会混乱 select_for_update
            cus_object = models.Customer.objects.filter(id=pk, active=1).select_for_update().first()
                # 类型为扣款  余额小于扣款 则账户余额不足
            if charge_type == 2 and cus_object.balance < amount:
                return JsonResponse({'status': False, 'detail': {'amount': ["账户余额不足只有:{}".format(cus_object.balance)]}})
                # print(charge_type,type(charge_type))

            if charge_type == 1:
                cus_object.balance = cus_object.balance + amount
            else:
                cus_object.balance = cus_object.balance - amount
            cus_object.save()
                # 生成交易记录
                # print('=======================', form.instance) TransactionRecord object (None)

            form.instance.customer = cus_object
            form.instance.creator_id = request.nb_user.id
            form.save()
    except Exception as e:
        return JsonResponse({'status': False, 'detail': {'amount': ["操作失败"]}})
    return JsonResponse({'status': True})
